package model;


import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class Round extends PersistentEntity {
  private SortedSet<Vote> votes;
  private int qtyA;
  private int qtyB;
  private Room room;
  private Integer result;
  

  public Round(Room room){
    super();
    this.votes = new TreeSet<Vote>();
    this.qtyA = 0;
    this.qtyB = 0;
    this.result = null;
    this.room = room;
  }

  public int getResult(){
    if(this.isClosed()){
      calculateScoresForUsers();
      return result;
    }else{
      throw new RuntimeException("You can not know the result of a round that is still opened");
    }
  }
  
  
  
  
  
  public boolean isClosed() {
    //TODO: que haya expirado el time
    if(votes.size() == room.getQUsers()){
      return true;
    }
    return false;
  }

  /**
   * Agrega un voto a la ronda. Si el usuario ya ha votado se lanza una exepcion
   * 
   * @param vote
   * @throws Exception
   */
  public void addVote(Vote vote) {
    if(isClosed()){
      throw new RuntimeException("The round is closed. No one can vote anymore.");
    }
    
      if (votes.contains(vote)) {
        throw new RuntimeException("The user has already voted for this round");
      }
      votes.add(vote);
      if (vote.getAnswer().equals(Vote.AnswerType.A)) {
        qtyA++;
      } else {
        qtyB++;
      }
  }

  /**
   * 
   * @return el cambio en el valor de la accion (A suma; B resta)
   */
  public void calculateScoresForUsers() {
    Integer As = this.qtyA, Bs = this.qtyB;
    Iterator<Vote> i = this.votes.iterator();
    Vote.AnswerType winnerAnswer;
    Integer result;

    // si As == Bs, hay empate, no se toma en cuenta el ultimo voto
    if (As == Bs) {
      Vote remove = this.getLastVote();
      if (remove.getAnswer().equals(Vote.AnswerType.A)) {
        As -= 1;
      } else {
        Bs -= 1;
      }
    }
    if (As > Bs) {
      winnerAnswer = Vote.AnswerType.B;
    } else {
      winnerAnswer = Vote.AnswerType.A;
    }
    result = Math.abs(As - Bs);
    this.result = result;
    
    while (i.hasNext()) {
      Vote v = i.next();
      if (v.getAnswer().equals(winnerAnswer)) {
        v.setPoints(result);
      } else {
        v.setPoints((-1) * result);
      }
    }
    return;
  }

  private Vote getLastVote() {
    return votes.last();
  }

  public Room getRoom() {
    return room;
  }

  
  
  
  
  
  
}
